#第8章 面向对象编程
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
class MyClass(object):
    i = '小明'
    def f(self):
        return 'hello world %s' % self.i

my_class = MyClass()
print('类中的属性是：',my_class.i)
print('类中方法的返回是：',my_class.f())

print('-----------类的初始化-----------')
class MyClass2(object):
    i = 123
    def __init__(self,name1,age1):
        self.name = name1
        self.age = age1

    def f(self):
        return 'hello %s,you are %s years old!' % (self.name,self.age)
        # return 'hello ',self.name,' ,you are ',self.age,'years old!'



my_class2 = MyClass2('小明','23')
print('类中的属性是：',my_class2.name)
print('类中的属性是：',my_class2.age)
print('类中方法的返回是：',my_class2.f())

print('-----------类的访问权限-----------')
print('-----------类的访问权限1：直接访问类的属性和方法-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def info(self):
        print('hello %s,you are %s years old!' % (self.name,self.age))

stu = Student('小明','23')
stu.info()
stu.name = '小张'
stu.age = '24'
stu.info()

print('-----------类的访问权限2：访问私有属性-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    def info(self):
        print('hello %s,you are %s years old!' % (self.__name, self.__age))

# stu = Student('小明','23')
# stu.info()
# stu.__name = '小张'
# stu.__age = '24'
# stu.info()

print('-----------类的访问权限3：使用get,set方法操作私有变量-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    def info(self):
        print('hello %s,you are %s years old!' % (self.__name,self.__age))

    def get_name(self):
        return self.__name

    def set_name(self,name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self,age):
        self.__age = age
stu = Student('小明','23')
stu.info()
stu.set_name('小张')
print('修改后的姓名是：',stu.get_name())
stu.set_age('24')
print('修改后的年龄是',stu.get_age())

print('-----------类的访问权限4：访问私有方法-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __info(self):
        print('hello %s,you are %s years old!' % (self.name,self.age))

    def foo(self):
        self.__info()

stu = Student('小明','23')
stu.foo()

print('-----------继承-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Animal(object):
    def run(self):
        print('animal is running....')

class Dog(Animal):
    pass

class Cat(Animal):
    pass

dog = Dog()
dog.run()
cat = Cat()
cat.run()

print('-----------多态-----------')
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Animal(object):
    def run(self):
        print('animal is running....')

class Dog(Animal):
    def run(self):
        print('dog is running....')

class Cat(Animal):
    def run(self):
        print('cat is running...')

dog = Dog()
dog.run()
cat = Cat()
cat.run()
print('dog是否是animal类型',isinstance(dog,Animal))
print('dog是否是dog类型',isinstance(dog,Animal))

print('-----------type()函数-----------')
print(type('abc'))
print(type(123))
print(type(None))
print(type(abs))

print(type('abc')==str)
print(type(123)==int)

print('-----------判断一个对象是否是函数-----------')
import types
def func():
    pass

print(type(func)==types.FunctionType)
print(type(abs)==types.BuiltinFunctionType)
print(type(lambda x,y,z:x+y+z)==types.LambdaType)
print(type(x for x in range(1,10))==types.GeneratorType)

print('-----------dir()函数-----------')
print(dir('abc'))

print('-----------类的专有方法-----------')
class Student(object):
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    def __str__(self):
        return '学生名称是：%s,学生的年龄是：%s' % (self.__name,self.__age)

print(Student('小明','23'))
stu_abc = Student('小宇','24')
print(stu_abc)

print('-----------__iter__-----------')
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a、b

    def __iter__(self):
        return self # 实例本身就是迭代对象，故返回自己

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration();
        return self.a # 返回下一个值

for n in Fib():
    print(n)

print('-----------__getitem__-----------')
class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

print(Fib()[3])

print('-----------__getattr__-----------')
class Student1(object):

    def __getattr__(self, attr):
        if attr == 'score':
            return 95


stu1 = Student1()
print(stu1.score)

print('-----------__call__-----------')
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
    def __init__(self,name):
        self.name = name

    def __call__(self, *args, **kwargs):
        print('姓名是：%s' % self.name)

stu2 = Student('小明')
stu2()

print('-----------通过callable函数判断对象是否可以调用-----------')
print(callable(Student('小明')))
print(callable(Student1()))
print(callable(max))
print(callable([1,2,3]))

print('-----------牛刀小试，出行建议-----------')
class WeatherSeach(object):
    def __init__(self,input_daytime):
        self.input_daytime = input_daytime

    def search_visible(self):
        visible = 0
        if self.input_daytime == 'daytime':
            visible = 6
        elif self.input_daytime == 'night':
            visible = 2
        return visible

    def search_temperature(self):
        temperature = 0
        if self.input_daytime == 'night':
            temperature = 16
        elif self.input_daytime == 'daytiem':
            temperature = 26

        return temperature

class OutAdvice(WeatherSeach):
    def __init__(self,input_daytime):
        WeatherSeach.__init__(self,input_daytime)

    def search_temperature(self):
        we_use = 'none'
        if self.input_daytime == 'daytime':
            we_use = '骑自行车'
        elif self.input_daytime == 'night':
            we_use = '开车'
        return we_use

    def take_advice(self):
        we_use = self.search_temperature()
        visible = self.search_visible()
        if visible >= 6:
            print('今天天气不错，可以%s出行' % we_use)
        elif 0 < visible <= 2:
            print('今天天气不好，只能%s出行' % we_use)
        else:
            print('输入的内容有误，无法给出相应的建议！')

oa = OutAdvice('night')
oa.take_advice()

print('-----------问题解答1：双下划綫开头的变量是否一定不能通过外部访问-----------')
class Student(object):
    def __init__(self,name,score):
        self.__name = name
        self.__socre = score

    def info(self):
        print('学生的姓名是：%s,成绩是：%s' % (self.__name,self.__socre))

    def get_score(self):
        return self.__socre

stu3 = Student('小宇','94')
stu3.info()
#print('分数是：',stu3._Student__score) #报错
print('分数是：',stu3.get_score())

